using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Threading;

namespace cb0tServer
{
    class TOR
    {
        private List<IPAddress> items = new List<IPAddress>();
        private Thread thread;
        private bool updating = false;
     //   private bool first_time = true;
        private DateTime last_update = DateTime.Now;

        public String Time
        {
            get
            {
                return this.last_update.ToShortDateString() + " " + this.last_update.ToShortTimeString();
            }
        }

        public String ItemCount
        {
            get
            {
                return this.items.Count.ToString();
            }
        }

        private static String[] HotspotShield = new String[]
        {
            "46.16.",
            "64.55.",
            "69.22.",
            "69.162.",
            "69.167.",
            "74.115.",
            "128.241.",
            "140.174.",
            "204.2.",
            "206.14.",
            "209.107.",
            "199.255."
        };

        public bool IsTor(IPAddress ip)
        {
            if (this.updating)
                return false;

            String str = ip.ToString();

            foreach (String hs in HotspotShield)
                if (str.StartsWith(hs))
                    return true;

            return this.items.Contains(ip);
        }

        public void Update()
        {
            this.thread = new Thread(new ThreadStart(this.Work));
            this.thread.Start();
        }

        public void Update(IPAddress ip)
        {
            if (!this.updating)
            {
                this.items.Add(ip);
                this.Save();
            }
        }

        private long ip2long(IPAddress value)
        {
            byte[] bytes = value.GetAddressBytes();
            Array.Reverse(bytes);
            return (long)BitConverter.ToInt32(bytes, 0);
        }

        private IPAddress long2ip(long value)
        {
            byte[] bytes = BitConverter.GetBytes((Int32)value);
            Array.Reverse(bytes);
            return new IPAddress(bytes);
        }

        private bool Load()
        {
            try
            {
                if (File.Exists(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/proxyblacklist"))
                {
                    String[] lines = File.ReadAllLines(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/proxyblacklist");

                    if (lines.Length > 1)
                    {
                        long i;

                        foreach (String l in lines)
                            if (long.TryParse(l, out i))
                                this.items.Add(this.long2ip(i));
                    }
                }
            }
            catch { return false; }

            return true;
        }

        private void Save()
        {
            if (this.items.Count > 0)
            {
                List<String> strs = new List<String>();
                this.last_update = DateTime.Now;

                foreach (IPAddress ip in this.items)
                {
                    long i = this.ip2long(ip);
                    strs.Add(i.ToString());
                }

                try
                {
                    while (this.items.Count > 3000)
                        this.items.RemoveRange(0, 100);

                    File.WriteAllLines(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/proxyblacklist", strs.ToArray());
                }
                catch { }
            }
        }

        private void Work()
        {
            this.updating = true;

            this.items.Clear();
            bool loaded = this.Load();

            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://proxy.org/tor_blacklist.txt");
                request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; Media Center PC 5.0)";
                StreamReader stream = new StreamReader(request.GetResponse().GetResponseStream());

                int counter = 0;

                while (!stream.EndOfStream)
                {
                    String line = stream.ReadLine();

                    if (line.StartsWith("RewriteCond %{REMOTE_ADDR} ^"))
                    {
                        line = line.Replace("RewriteCond %{REMOTE_ADDR} ^", "");
                        line = line.Replace("[OR]", "");
                        line = line.Replace("$", "");
                        line = line.Replace("\\", "");
                        line = line.Trim();
                        IPAddress ip;

                        if (IPAddress.TryParse(line, out ip))
                            if (!this.items.Contains(ip))
                                this.items.Add(ip);
                    }

                    if (counter++ > 2000)
                        break;
                }
            }
            catch { }

            this.Save();
            this.updating = false;
        }

    }
}
